-module(server).
-import(werkzeug, [get_config_value/2, logging/2, timeMilliSecond/0, to_String/1]).
-import(hbq, [dropmessage/4]).
-import(dlq, [get/2, add/3, getMaxNumber/1, getMinNumber/1]).
-compile(export_all).


%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%% Start 
start() ->
%Read Configs

  {ok, ConfigListe} = file:consult("server.cfg"),
  {ok, Lifetime} = get_config_value(latency, ConfigListe),
  {ok, Name} = get_config_value(servername, ConfigListe),
  {ok, ClientLifeTime} = get_config_value(clientlifetime, ConfigListe),

  Pid = whereis(Name),
  if Pid == undefined ->
    ServerPid = spawn(fun() -> bornServer(Lifetime, 1, ClientLifeTime) end),
    register(Name, ServerPid),
    werkzeug:logging("NServer.log", lists:concat(["Server Startzeit: ", werkzeug:timeMilliSecond(), " mit PID ", werkzeug:to_String(ServerPid), "\n"])),
    ServerPid;
    true -> "Prozess laueft noch!"
  end.

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%% bornServer 
bornServer(Lifetime, Nr, ClientLifeTime) ->
  loop(Lifetime, Nr, hbq:createNew(), dlq:createNew(), [], ClientLifeTime).

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%% Main Server loop
loop(Lifetime, Nr, Holdback, Delivery, Clientlist,ClientLifeTime) ->
  receive
    {getmsgid, PID} ->
      PID ! {nid, Nr},
      werkzeug:logging("NServer.log", lists:concat(["Server: Nachrichtennummer ", to_String(Nr), " an ", to_String(PID), " gesendet\n"])),
      loop(Lifetime, Nr + 1, Holdback, Delivery, Clientlist, ClientLifeTime);

    {dropmessage, {Nachricht, Number}} ->
      Msg = lists:concat([Nachricht, " HBQ In: ", werkzeug:timeMilliSecond()]),
      werkzeug:logging("NServer.log", lists:concat(["Nachricht: ", to_String(Number), " HBQ In: ", werkzeug:timeMilliSecond(), "-dropmessage \n"])),
      [NewHoldBack, NewDelivery] = hbq:dropmessage(Msg, Number, Holdback, Delivery),
      werkzeug:logging("NServer.log", lists:concat(["] von HBQ in DLQ transferiert. \n"])),
      loop(Lifetime, Nr, NewHoldBack, NewDelivery, Clientlist, ClientLifeTime);

    {getmessages, ClientPID} ->
      NewClientlist = nachrichtendienst:getNachrichten(ClientPID, Clientlist, Delivery, ClientLifeTime),

      loop(Lifetime, Nr, Holdback, Delivery, NewClientlist, ClientLifeTime);

    {clienttimeout, PID} ->
      NewClients = proplists:delete(PID, Clientlist),
      logging("NServer.log", lists:concat(["client ", to_String(PID), " wird vergessen! *************\n"])),
      loop(Lifetime, Nr, Holdback, Delivery, NewClients, ClientLifeTime);

    Any -> io:format("Error: Received Something:~p\n", [Any]),
      loop(Lifetime, Nr, Holdback, Delivery, Clientlist, ClientLifeTime)

  after (Lifetime * 1000) -> io:format("Server  Lifetime Ende.~n"), exit(0)
  end.









